package com.dianzhihan.http4;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

@Controller
public class CookieController {
    // 专门用来发凭证（cookie）的
    @GetMapping("/set-cookie")
    public void setCookie(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // servlet 里的处理方式
        // 不要用中文，因为 cookie 的设置和携带是放在请求响应头中的，字符集编码是西文格式，不支持中文
        Cookie cookie1 = new Cookie("name", "dianzhihan");
        Cookie cookie2 = new Cookie("course", "java");
        Cookie cookie3 = new Cookie("today", "2023-02-01");

        response.addCookie(cookie1);
        response.addCookie(cookie2);
        response.addCookie(cookie3);

        // 设置响应体的字符集编码
        response.setCharacterEncoding("utf-8");
        // 设置响应体的格式 —— 纯文本
        response.setContentType("text/plain");
        // 写响应内容
        response.getWriter().println("cookie 设置成功，请观察开发者工具的 网络面板 和 应用面板");
    }

    // 记录用户访问次数
    private final Map<String, Integer> countMap = new HashMap<>();  // 这个 map 就是就是房子
    private final Map<String, Map<String, Object>> 模拟session的结构 = new HashMap<>();

    // 咱模拟了一个 session
    @GetMapping("/use-cookie")
    public void useCookie(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String id = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("id")) {
                    id = cookie.getValue();
                }
            }
        }

        Integer count = null;
        if (id == null) {
            // cookie 中没有携带 id，认为是用户第一次访问

            // 将当前时间戳当作这次用户的访问标识
            long ts = System.currentTimeMillis();
            System.out.println("是第一次访问");
            id = String.valueOf(ts);
            Cookie cookie = new Cookie("id", id);
            response.addCookie(cookie);

            count = 1;
            countMap.put(id, count);
        } else {
            // cookie 中携带了 id，说明之前是访问过的

            System.out.println("不是第一次访问");

            count = countMap.get(id);
            if (count == null) {
                // 由于程序重启，内存中的 countMap 的数据丢了
                // 所以当成第一次吧
                count = 1;
            } else {
                count += 1;
            }
            countMap.put(id, count);
        }

        System.out.println("现在统计的所有人的访问次数:");
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            System.out.printf("%s => %d\r\n", entry.getKey(), entry.getValue());
        }


        // 设置响应体的字符集编码
        response.setCharacterEncoding("utf-8");
        // 设置响应体的格式 —— 纯文本
        response.setContentType("text/plain");
        // 写响应内容
        if (count == 1) {
            response.getWriter().println("第 1 次访问，您的 id 是: " + id);
        } else {
            response.getWriter().printf("欢迎 %s 的第 %d 次访问\r\n", id, count);
        }
    }

    // 统计访问次数的功能-2
    @GetMapping("/use-session")
    public void useSession(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // session 的代码相对重要一些，注册/登录用户必须依赖

//        HttpSession session1 = request.getSession(false);
//        HttpSession session2 = request.getSession(true);

        // 默认的 Cookie 使用 JSESSIONID
        // 咱的代码中只看到了 Session 的使用，没看到 cookie 的使用，但 cookie 在背后默默地支持
        HttpSession session = request.getSession(false);
        System.out.println(session);

        int currentCount;
        // session 对象也是个 key-value 结构
        if (session == null) {
            // 说明是第一次访问（或者因为其他原因数据对不上了）
            session = request.getSession();
            session.setAttribute("count", 1);
            currentCount = 1;
        } else {
            // 说明不是第一次访问，所以我们才能拿到 session 对象
            Integer count = (Integer) session.getAttribute("count");
            if (count == null) {
                // 原则上是不应该出现这种情况的
                throw new RuntimeException("不应该走到这里");
            }

            count += 1;
            session.setAttribute("count", count);
            currentCount = count;
        }

        // 设置响应体的字符集编码
        response.setCharacterEncoding("utf-8");
        // 设置响应体的格式 —— 纯文本
        response.setContentType("text/plain");
        // 写响应内容
        response.getWriter().printf("本请求的 session 对象为: %s，访问次数为: %d\r\n", session, currentCount);
    }
}
